home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / SRC / FX / FXRENDER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-24  |  6.7 KB  |  239 lines

  1. /* -*- mode: C; tab-width:8;  -*-
  2.  
  3.              fxrender.c - 3Dfx VooDoo RenderVB driver function support
  4. */
  5.  
  6. /*
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Library General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Library General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Library General Public
  18.  * License along with this library; if not, write to the Free
  19.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  * See the file fxapi.c for more informations about authors
  22.  *
  23.  */
  24.  
  25. #if defined(FX)
  26.  
  27. #include "fxdrv.h"
  28.  
  29. /*
  30.  * Render a line segment from VB[v1] to VB[v2] when either one or both
  31.  * endpoints must be clipped.
  32.  */
  33. static void fxRenderClippedLine( GLcontext *ctx, GLuint v1, GLuint v2 )
  34. {
  35.   GLfloat ndc_x,ndc_y,ndc_z;
  36.   struct vertex_buffer *VB=ctx->VB;
  37.   fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
  38.   GrVertex *gWin=fxMesa->gWin;
  39.  
  40.   /*
  41.    * Clipping may introduce new vertices.  New vertices will be stored
  42.    * in the vertex buffer arrays starting with location VB->Free.  After
  43.    * we've rendered the line, these extra vertices can be overwritten.
  44.    */
  45.   VB->Free = VB_MAX;
  46.  
  47.   /* Clip against view volume */
  48.   if (gl_viewclip_line( ctx, &v1, &v2 )==0)
  49.     return;
  50.  
  51.   /* Transform from clip coords to ndc:  ndc = clip / W */
  52.   if (VB->Clip[v1][3] != 0.0F) {
  53.     GLfloat wInv = 1.0F / VB->Clip[v1][3];
  54.     ndc_x = VB->Clip[v1][0] * wInv;
  55.     ndc_y = VB->Clip[v1][1] * wInv;
  56.     ndc_z = VB->Clip[v1][2] * wInv;
  57.   } else {
  58.     /* Can't divide by zero, so... */
  59.     ndc_x = ndc_y = ndc_z = 0.0F;
  60.   }
  61.  
  62.   /* Map ndc coord to window coords. */
  63.   VB->Win[v1][0] = ndc_x * ctx->Viewport.Sx + ctx->Viewport.Tx;
  64.   VB->Win[v1][1] = ndc_y * ctx->Viewport.Sy + ctx->Viewport.Ty;
  65.   VB->Win[v1][2] = ndc_z * ctx->Viewport.Sz + ctx->Viewport.Tz;
  66.  
  67.   /* Transform from clip coords to ndc:  ndc = clip / W */
  68.   if (VB->Clip[v2][3] != 0.0F) {
  69.     GLfloat wInv = 1.0F / VB->Clip[v2][3];
  70.     ndc_x = VB->Clip[v2][0] * wInv;
  71.     ndc_y = VB->Clip[v2][1] * wInv;
  72.     ndc_z = VB->Clip[v2][2] * wInv;
  73.   } else {
  74.     /* Can't divide by zero, so... */
  75.     ndc_x = ndc_y = ndc_z = 0.0F;
  76.   }
  77.  
  78.   /* Map ndc coord to window coords. */
  79.   VB->Win[v2][0] = ndc_x * ctx->Viewport.Sx + ctx->Viewport.Tx;
  80.   VB->Win[v2][1] = ndc_y * ctx->Viewport.Sy + ctx->Viewport.Ty;
  81.   VB->Win[v2][2] = ndc_z * ctx->Viewport.Sz + ctx->Viewport.Tz;
  82.  
  83.   (*ctx->Driver.RasterSetup)(ctx,v1,v1+1);
  84.   (*ctx->Driver.RasterSetup)(ctx,v2,v2+1);
  85.  
  86.   grDrawLine(&gWin[v1],&gWin[v2]);
  87. }
  88.  
  89. /*
  90.  * Render a polygon in which at least one vertex has to be clipped.
  91.  * Input:  n - number of vertices
  92.  *         vlist - list of vertices in the polygon.
  93.  *                 CCW order = front facing.
  94.  */
  95. static void fxRenderClippedPolygon( GLcontext *ctx, GLuint n, GLuint vlist[] )
  96. {
  97.   struct vertex_buffer *VB = ctx->VB;
  98.   GLfloat (*win)[3] = VB->Win;
  99.   fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
  100.   GrVertex *gWin=fxMesa->gWin;
  101.  
  102.   /*
  103.    * Clipping may introduce new vertices.  New vertices will be stored
  104.    * in the vertex buffer arrays starting with location VB->Free.  After
  105.    * we've rendered the polygon, these extra vertices can be overwritten.
  106.    */
  107.   VB->Free = VB_MAX;
  108.  
  109.   /* Clip against view volume in clip coord space */
  110.   n = gl_viewclip_polygon( ctx, n, vlist );
  111.   if (n<3)
  112.     return;
  113.  
  114.   /* Transform new vertices from clip to ndc to window coords.    */
  115.   /* ndc = clip / W    window = viewport_mapping(ndc)             */
  116.   /* Note that window Z values are scaled to the range of integer */
  117.   /* depth buffer values.                                         */
  118.   {
  119.     GLfloat sx = ctx->Viewport.Sx;
  120.     GLfloat tx = ctx->Viewport.Tx;
  121.     GLfloat sy = ctx->Viewport.Sy;
  122.     GLfloat ty = ctx->Viewport.Ty;
  123.     GLfloat sz = ctx->Viewport.Sz;
  124.     GLfloat tz = ctx->Viewport.Tz;
  125.     GLuint i;
  126.  
  127.     /* Only need to compute window coords for new vertices */
  128.     for (i=VB_MAX; i<VB->Free; i++) {
  129.       if (VB->Clip[i][3] != 0.0F) {
  130.     GLfloat wInv = 1.0F / VB->Clip[i][3];
  131.     win[i][0] = VB->Clip[i][0] * wInv * sx + tx;
  132.     win[i][1] = VB->Clip[i][1] * wInv * sy + ty;
  133.     win[i][2] = VB->Clip[i][2] * wInv * sz + tz;
  134.       }
  135.       else {
  136.     /* Can't divide by zero, so... */
  137.     win[i][0] = win[i][1] = win[i][2] = 0.0F;
  138.       }
  139.     }
  140.  
  141.     if(VB->Free > VB_MAX)
  142.       (*ctx->Driver.RasterSetup)(ctx,VB_MAX,VB->Free);
  143.   }
  144.  
  145.   {
  146.     GLint i;
  147.     GLuint j0=vlist[0];
  148.  
  149.     for (i=2;i<n;i++)
  150.       grDrawTriangle(&gWin[j0],&gWin[vlist[i-1]],&gWin[vlist[i]]);
  151.   }
  152. }
  153.  
  154. /************************************************************************/
  155. /************************ RenderVB functions ****************************/
  156. /************************************************************************/
  157.  
  158. #undef FXRENDERVB_NAME
  159. #undef RVB_COLOR
  160. #define FXRENDERVB_NAME fxDDRenderVBFlat
  161. #define RVB_COLOR(pv) grConstantColorValue(FXCOLOR(VB->Color[pv][0], \
  162.                            VB->Color[pv][1], \
  163.                            VB->Color[pv][2], \
  164.                            VB->Color[pv][3]));
  165. #include "fxrender.h"
  166.  
  167. #undef FXRENDERVB_NAME
  168. #undef RVB_COLOR
  169. #define FXRENDERVB_NAME fxDDRenderVBSmooth
  170. #define RVB_COLOR(pv)
  171. #include "fxrender.h"
  172.  
  173. #undef FXRENDERVB_NAME
  174. #undef RVB_COLOR
  175.  
  176. tfxRenderVBFunc fxDDChooseRenderVBFunction(GLcontext *ctx)
  177. {
  178.   fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
  179.  
  180.   if((ctx->RasterMask & FRONT_AND_BACK_BIT) ||
  181.      (ctx->Polygon.OffsetAny) || /* Not yet supported */
  182.      (ctx->Light.Model.TwoSide) ||
  183.      (ctx->Transform.AnyClip) ||
  184.      (ctx->Point.SmoothFlag) ||
  185.      (ctx->Line.SmoothFlag) ||
  186.      (ctx->Polygon.Unfilled) ||
  187.      (ctx->Polygon.SmoothFlag) ||
  188.      (ctx->Polygon.StippleFlag) ||
  189.      (ctx->RenderMode!=GL_RENDER)) {
  190.     grCullMode(GR_CULL_DISABLE);
  191.     return NULL;
  192.   }
  193.  
  194.   fxMesa->currentFrontFace=ctx->Polygon.FrontFace;
  195.  
  196.   if(ctx->Polygon.CullFlag) {
  197.     switch(ctx->Polygon.CullFaceMode) {
  198.     case GL_BACK:
  199.       if(ctx->Polygon.FrontFace==GL_CCW)
  200.     grCullMode(GR_CULL_NEGATIVE);
  201.       else
  202.     grCullMode(GR_CULL_POSITIVE);
  203.       break;
  204.     case GL_FRONT:
  205.       if(ctx->Polygon.FrontFace==GL_CCW)
  206.     grCullMode(GR_CULL_POSITIVE);
  207.       else
  208.     grCullMode(GR_CULL_NEGATIVE);
  209.       break;
  210.     case GL_FRONT_AND_BACK:
  211.       grCullMode(GR_CULL_DISABLE);
  212.       return NULL;
  213.     default:
  214.       ; /*nothing*/
  215.     }
  216.   } else
  217.     grCullMode(GR_CULL_DISABLE);
  218.  
  219.   if(ctx->Light.ShadeModel==GL_SMOOTH)
  220.     return fxDDRenderVBSmooth;
  221.  
  222.   return fxDDRenderVBFlat;
  223. }
  224.  
  225.  
  226. #else
  227.  
  228.  
  229. /*
  230.  * Need this to provide at least one external definition.
  231.  */
  232.  
  233. int gl_fx_dummy_function_render(void)
  234. {
  235.   return 0;
  236. }
  237.  
  238. #endif  /* FX */
  239.